export interface WetAirStateConfig {
  range: [number, number]
  message: string
}

/**
 * #### 湿空气状态参数接口
 */
export interface WetAirState {
  /**
   * #### 露点温度，单位℃
   */
  dewTemperature: number
  /**
   * #### 干球温度，单位℃
   */
  dryTemperature: number
  /**
   * #### 比焓值，单位kJ/kg
   */
  enthalpy: number
  /**
   * #### 含湿量，单位Kg/kg
   */
  humidity: number
  /**
   * #### 相对湿度，单位%
   */
  relativeHumidity: number
  /**
   * #### 湿球温度，单位℃
   */
  wetTemperature: number
}

/**
 * #### 湿空气状态参数键名类型接口
 */
export type WetAirStateKeys = keyof WetAirState

/**
 * #### 湿空气状态参数对接口
 */
type ParameterPair<
  T extends WetAirStateKeys,
  U extends WetAirStateKeys
> = T extends U ? never : { [K in T | U]: WetAirState[K] }

/**
 * ### 湿空气状态具体参数对接口
 * 1、参数对要求两个泛型参数必须不同；
 * 2、泛型参数必须是WetAirStateKeys类型；
 * 3、泛型参数顺序有特殊要求，因为在策略工厂模式中有sort字母排序；
 * 4、td与d;tw与h不能成对出现；
 */
export type WetAirStateParameter =
  | ParameterPair<'dewTemperature', 'dryTemperature'>
  | ParameterPair<'dewTemperature', 'enthalpy'>
  | ParameterPair<'dewTemperature', 'relativeHumidity'>
  | ParameterPair<'dewTemperature', 'wetTemperature'>
  | ParameterPair<'dryTemperature', 'enthalpy'>
  | ParameterPair<'dryTemperature', 'humidity'>
  | ParameterPair<'dryTemperature', 'relativeHumidity'>
  | ParameterPair<'dryTemperature', 'wetTemperature'>
  | ParameterPair<'enthalpy', 'humidity'>
  | ParameterPair<'enthalpy', 'relativeHumidity'>
  | ParameterPair<'humidity', 'relativeHumidity'>
  | ParameterPair<'wetTemperature', 'humidity'>
  | ParameterPair<'wetTemperature', 'relativeHumidity'>

/**
 * #### 湿空气状态具体参数键名类型接口
 */
export type ParameterKey<T> = T extends WetAirStateParameter ? keyof T : never

/**
 * ### 一元函数类型
 */
export type UnaryFunc = (x: number) => number
/**
 * ### 二元函数类型
 */
export type BinaryFunc = (x: number, y: number) => number
/**
 * ### 三元函数类型
 */
export type TernaryFunc = (x: number, y: number, z: number) => number
/**
 * ### 多元函数类型
 */
export type UnionFunc = UnaryFunc | BinaryFunc | TernaryFunc

/**
 * ### 计算策略接口
 */
export interface CalculationStrategy {
  calculate(params: WetAirStateParameter, pressure: number): WetAirState
}
